from skimage.segmentation import mark_boundaries
# from skimage.segmentation import slic_superpixels
from skimage.measure import regionprops
from skimage.feature import peak_local_max
from skimage import filters 
from skimage.morphology import ball,disk
from skimage.color import rgb2gray
from scipy import ndimage as ndi
from skimage.util import img_as_float
from skimage import io
import matplotlib.pyplot as plt
import skimage.segmentation
import skimage
import imageio
import numpy as np
import time
import cv2
import os


def image_equalizeHist(img,color='HSV'):
    if color =='HSV':
        img_HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        H, S, V = cv2.split(img_HSV)
        eq_V = cv2.equalizeHist(V)
        img_HSV = cv2.merge([H, S, eq_V])
        img_hist = cv2.cvtColor(img_HSV, cv2.COLOR_HSV2BGR)
    elif color == 'YCrCb':
        img_YCrCb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
        Y, Cr, Cb = cv2.split(img_YCrCb)
        eq_Y = cv2.equalizeHist(Y)
        img_YCrCb = cv2.merge([eq_Y, Cr, Cb])
        img_hist = cv2.cvtColor(img_YCrCb, cv2.COLOR_YCrCb2BGR)
    # elif color == 'YUV':
    #     img_YUV = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
    #     L, a, b = cv2.split(img_YUV)
    #     eq_L = cv2.equalizeHist(L)
    #     img_YUV = cv2.merge([eq_L, a, b])
    #     img_hist = cv2.cvtColor(img_YUV, cv2.COLOR_YUV2BGR)
    elif color == 'LAB':
        img_LAB = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
        L, A, B = cv2.split(img_LAB)
        eq_L = cv2.equalizeHist(L)
        img_LAB = cv2.merge([eq_L, A, B])
        img_hist = cv2.cvtColor(img_LAB, cv2.COLOR_Lab2BGR)
    elif color == 'gray':
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img_hist = cv2.equalizeHist(img_gray)
    return img_hist


def image_blur(img,blur="GaussianBlur"):
    if blur=="GaussianBlur":
        img_blur = cv2.GaussianBlur(img,(5,5),0)
    elif blur=="medianBlur":
        img_blur = cv2.medianBlur(img, 5)
    elif blur=="blur":
        img_blur = cv2.blur(img, (3,3))
    elif blur=="bilateralFilter":
        img_blur = cv2.bilateralFilter(img,9,75,75)
    return img_blur


def image_felzenszwalb(args):
    [image_path]=args
    image = img_as_float(io.imread(image_path))
    plt.figure("source")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(image)

    filter_image = filters.median(image, ball(9))
    
    label = skimage.segmentation.felzenszwalb(
        filter_image, 
        scale=500, 
        sigma=0.8, 
        min_size=20,
        # channel_axis=True
    )
    out = mark_boundaries(
        image,
        label,
        color=(1,0,0),
        outline_color=(1, 0, 0),
        mode='outer'
    )
    plt.figure("target")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(out)
  
    plt.show()
    return


def image_thresh_otsu(args):
    [image_path]=args

    # image = img_as_float(io.imread(image_path))

    img_bgr = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), 1)
    '''直方图均衡化,去噪'''
    img_hist = image_equalizeHist(img_bgr,'HSV')
    img_blur = image_blur(img_hist, 'medianBlur')
    img_gray = cv2.cvtColor(img_blur, cv2.COLOR_BGR2GRAY)
  
    bin_image = img_gray > filters.threshold_otsu(img_gray)
    # out = mark_boundaries(
    #     cv2.cvtColor(img_blur, cv2.COLOR_BGR2RGB),
    #     bin_image,
    #     color=(1,0,0),
    #     outline_color=(1, 0, 0),
    #     mode='outer'
    # )

    plt.figure("mask")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(bin_image,cmap="gray")

    plt.show()
    return


def image_isodata(args):
    [image_path]=args

    image = img_as_float(io.imread(image_path))
    plt.figure("source")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(image)
    
    filter_image = filters.gaussian(image,sigma=2,mode='nearest',channel_axis=True) 
    img_gray = rgb2gray(filter_image)
    img_gray = filters.gaussian(img_gray, sigma=2,mode='nearest',channel_axis=True)
    [min, normal, max]=filters.threshold_isodata(img_gray,nbins=256,return_all=True)
    bin_min_img = img_gray < min
    bin_nor_img = img_gray < normal
    bin_max_img = img_gray < max
   
    bin_min_img_mask = mark_boundaries(
        image,
        bin_min_img,
        color=(1,0,0),
        outline_color=(1, 0, 0),
        mode='outer'
    )
    plt.figure("bin_min_img")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(bin_min_img_mask)

    bin_nor_img_mask = mark_boundaries(
        image,
        bin_nor_img,
        color=(1,0,0),
        outline_color=(1, 0, 0),
        mode='outer'
    )
    plt.figure("bin_nor_img_mask")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(bin_nor_img_mask)

    bin_max_img_mask = mark_boundaries(
        image,
        bin_max_img,
        color=(1,0,0),
        outline_color=(1, 0, 0),
        mode='outer'
    )
    plt.figure("bin_max_img_mask")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(bin_max_img_mask)
    plt.show()
    return


def image_threshold_multiotsu(args):
    [image_path]=args

    image = img_as_float(io.imread(image_path))

    plt.figure("source")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(image)
    
    # filter_image = filters.median(image, ball(5))  # 中值滤波
    filter_rgb_image = filters.gaussian(image, sigma=2)  # 高斯滤波

    img_gray = rgb2gray(filter_rgb_image)
    # img_gray = filters.median(img_gray, disk(5))  # 中值滤波
    filter_img = filters.gaussian(img_gray, sigma=2)
    print(filters.threshold_multiotsu(filter_img))
    # bin_image = filter_img > 

    # out = mark_boundaries(
    #     image,
    #     bin_image,
    #     color=(1,0,0),
    #     outline_color=(1, 0, 0),
    #     mode='outer'
    # )

    # plt.figure("mask")
    # plt.subplot(111)
    # plt.axis("off")
    # plt.imshow(out)

    plt.show()
    return


def image_gabor(args):
    [image_path]=args
    image = img_as_float(io.imread(image_path))
    plt.figure("source")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(image)

    gray_image = rgb2gray(image)
    print(filters.try_all_threshold(gray_image))
    bin_image = gray_image > filters.try_all_threshold(gray_image)

    plt.figure("bin_image")
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(bin_image)

    plt.show()
    return

def image_kmeans(image_path,save_dir):
    k = 2  # 分类数
    max_iter = 50
    epsilon = 0.1  #  结果的精确性
    attempts = 10 
    flags = cv2.KMEANS_RANDOM_CENTERS  # cv2.KMEANS_RANDOM_CENTERS只是指示OpenCV最初随机分配集群的值。
    #cv2.TERM_CRITERIA_EPS :精确度（误差）满足epsilon停止
    #cv2.TERM_CRITERIA_MAX_ITER：迭代次数超过max_iter停止
    # 二者都满足
    criteria_type = cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER  
    img_bgr = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), 1)
    img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
    imeg_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
    pixel_values = img_rgb.reshape((-1, 3))
    pixel_values = np.float32(pixel_values)

    criteria = (criteria_type, max_iter, epsilon)  # 确定停止标准（type,max_iter,epsilon）
    _, labels,centers = cv2.kmeans(pixel_values, k, None, criteria, attempts, flags)
    
    mask = labels.reshape((imeg_gray.shape))

    plt.figure()
    plt.title(f'k={k},max_iter={max_iter},epsilon={epsilon}')
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(mask,cmap='Accent')
    name =f"{k}-{max_iter}-{epsilon}_1.png"
    plt.savefig(os.path.join(save_dir,name),bbox_inches='tight')

    img_line = mark_boundaries(img_rgb,mask,(1,0,0),mode='inner')

    plt.figure()
    plt.title(f'k={k},max_iter={max_iter},epsilon={epsilon}')
    plt.subplot(111)
    plt.axis("off")
    plt.imshow(img_line)
    name = f"{k}-{max_iter}-{epsilon}.png"
    plt.savefig(os.path.join(save_dir, name),bbox_inches='tight')

    plt.show()
    return


if __name__ == "__main__":
    '''help'''
    # print(help(cv2.kmeans))
    '''k-means'''
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # save_dir = r"E:\Yang\image"
    # image_kmeans(image_path,save_dir)
    '''计算Felsenszwalb基于图的高效图像分割'''
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # image_felzenszwalb([image_path])
    '''ostu分割'''
    # image_path = r"E:\Image2\cweqm5huoa4vae9xxypn53l0_0.jpg"
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # image_thresh_otsu([image_path])
    '''分水岭分割'''
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # image_watershed([image_path])
    '''isodata分割'''
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # image_isodata([image_path])
    ''''''
    # print(dir(filters))
    # print(help(filters.gaussian))
    # print(help(filters.threshold_isodata))
    # print(dir(skimage.segmentation))
    ''''''
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # image_threshold_multiotsu([image_path])
    ''''''
    '''gabor'''
    # image_path = r"E:\Image2\G50F008021_2_0_1_0.tif"
    # image_gabor([image_path])